#include "CEventSystem.h"

// private functions for use by the class only
void CEventSystem::DispatchEvents( CEvents* pEvents )
{
	pair<multimap<EVENTID,IListener*>::iterator, multimap<EVENTID,IListener*>::iterator> range;

	range = m_EventsDatabase.equal_range( pEvents->GetEvents() );

	for( multimap<EVENTID,IListener*>::iterator mmIter = range.first ; 
		mmIter != range.second ;
		++mmIter )
	{
		 (*mmIter).second->HandleEvents( pEvents );
	}
}
bool CEventSystem::RegisteredEvents( EVENTID eventsID, IListener* pTheListener )
{
	bool bIsRegistered = false;
	
	pair< multimap<EVENTID,IListener*>::iterator , multimap<EVENTID,IListener*>::iterator > range;
	
	range = m_EventsDatabase.equal_range( eventsID );

	for( multimap<EVENTID,IListener*>::iterator mmIter = range.first ;
			mmIter != range.second ;
			++ mmIter )
	{
		if( (*mmIter).second == pTheListener )
		{
			bIsRegistered = true;
			break;
		}
	}
	
	return bIsRegistered;

}

// public functions for user calls
CEventSystem* CEventSystem::GetInstance( void )
{
	static CEventSystem eventSys;
	return &eventSys;
}
void CEventSystem::RegisterListeners( EVENTID eventsID, IListener* pTheListener )
{
	if( !pTheListener || RegisteredEvents( eventsID, pTheListener ) ) 
		return;
	
	m_EventsDatabase.insert( make_pair( eventsID, pTheListener )  );

}
void CEventSystem::UnregisterListeners( EVENTID eventsID, IListener* pTheListener )
{
	if( !pTheListener )
		return;

	pair< multimap<EVENTID,IListener*>::iterator, multimap<EVENTID,IListener*>::iterator> range;
	range = m_EventsDatabase.equal_range( eventsID );
	for( multimap<EVENTID,IListener*>::iterator mmIter = range.first ;
		mmIter != range.second ; ++mmIter )
	{
		if( (*mmIter).second == pTheListener )
		{
			m_EventsDatabase.erase( mmIter );
			break;
		}
	}


}
void CEventSystem::ClearAllListeners( IListener* pTheListener )
{
	if( !pTheListener )
		return ;

	multimap<EVENTID,IListener*>::iterator mmIter = m_EventsDatabase.begin();

	while( mmIter != m_EventsDatabase.end() )
	{
		if( mmIter->second == pTheListener )
		{
			mmIter = m_EventsDatabase.erase( mmIter );
		}
		else
			mmIter++;
	}

}
void CEventSystem::SendEvents( EVENTID eventsID, void* pData )
{
	CEvents events( eventsID, pData );
	m_CurrEvents.push_back( events );
}
void CEventSystem::ProcessEvents( void )
{
	if( m_CurrEvents.size() != 0 )
	{
		for( unsigned int i = 0 ; i < m_CurrEvents.size() ; ++i )
		{
			DispatchEvents( &m_CurrEvents.front() );
			m_CurrEvents.pop_front();
		}
	}
}
void CEventSystem::ClearEvents( void )
{
		m_CurrEvents.clear();
}
void CEventSystem::ShutdownEventSystem( void )
{
	m_EventsDatabase.clear();
}